var PlayerManager = require('./playermanager');
var Log = require('../framework/Log');
var Util = require('util');
var Message = require('./messages');

function Channel(app,name){
    this.name = name;
    this.app = app;
    this.playerManager = new PlayerManager(app);
    this.total_player = 0;
};

Channel.prototype.onDestroy = function(){

};

Channel.prototype.hasPlayer = function(id){
    return this.playerManager.hasPlayer(id);
};

Channel.prototype.getPlayer = function(id){
    return this.playerManager.getPlayer(id);
};

Channel.prototype.enter = function(player){
    if(this.playerManager.hasPlayer(player.id)){
        Log.warn("[CHANNEL]player %s already in channel %s",player.id,this.name);
    }else{
        this.playerManager.addPlayer(player);
        this.total_player++;
    }
};

Channel.prototype.leave = function(id){
    if(!this.playerManager.hasPlayer(id)){
        Log.warn("[CHANNEL]player %s not in channel %s",id,this.name);
    }else{
       this.playerManager.delPlayer(id);
       this.total_player--;
    }
};

Channel.prototype.notifyAll = function(msg){
    this.playerManager.notifyAll(msg);
}

function WorldChannel(app,name){
    Channel.call(this,app,name);
}

Util.inherits(WorldChannel,Channel);

WorldChannel.prototype.enter = function(player){
    Channel.prototype.enter.call(this,player);
    var msg = new Message.EnterChannelNotify(this.name,player.id,player);
    this.notifyAll(msg);
};


WorldChannel.prototype.leave = function(id){
    Channel.prototype.leave.call(this,id);
    var msg = new Message.LeaveChannelNotify(this.name,id);
    this.notifyAll(msg);
};

function BattleChannel(app,name){
    Channel.call(this,app,name);
}

Util.inherits(BattleChannel,Channel);

BattleChannel.prototype.enter = function(player){

};

BattleChannel.prototype.leave = function(id){

};

function ChannelService(app){
    this.app = app;
    this.channels  = {};
    this.channel_map = {};
};

ChannelService.prototype.getChannel = function(name){
    return this.channels[name];
};

ChannelService.prototype.hasChannel = function(name){
    return this.channels.hasOwnProperty(name);
};

ChannelService.prototype.newChannel = function(name){
    if(name === "world"){
        this.channels[name] = new WorldChannel(app,name);
    }else if(name === "battle"){
        this.channels[name] = new BattleChannel(app,name);
    }
    else{
        this.channels[name] = new Channel(app,name);
    }
    Log.debug("[CHANNEL]channel %s created",name);
    return this.channels[name];
};

ChannelService.prototype.destroyChannel = function(name){
    if(this.channels.hasOwnProperty(name)){
        this.channels[name].onDestroy();
        delete this.channels[name];
    }
    Log.debug("[CHANNEL]channel %s destroyed",name);
};

ChannelService.prototype.enterChannel = function(name,player){
    if(!this.hasChannel(name)){
        this.newChannel(name);
    }
    this.channels[name].enter(player);
    this.channel_map[player.id] = this.channel_map[player.id] || {};
    this.channel_map[player.id][name] = true;
    Log.debug("[CHANNEL]%s enter channel %s",player.id,name);
};

ChannelService.prototype.leaveChannel = function(name,id){
    if(!this.hasChannel(name)){
        Log.warn("try leave channel not exist,name = %s,acc = %s",name,id);
    }
    this.channels[name].leave(id);
    if(this.channel_map[id] && this.channel_map[id][name]){
        delete this.channel_map[id][name];
    }
    Log.debug("[CHANNEL]%s leave channel %s",id,name);
    if(this.channels[name].total_player === 0){
        this.destroyChannel(name);
    }
};

ChannelService.prototype.leaveAllChannel = function(id){
    for(var t in this.channel_map[id]){
        if(this.channels.hasOwnProperty(t)){
            this.leaveChannel(t,id);
        }
    }
    delete this.channel_map[id];
};

ChannelService.prototype.start = function(){

};

module.exports = ChannelService;
